The present disclosure relates generally to computer software class verification, and, in particular, to class verification using caching for improved class-loading performance.
One of the more time consuming operations while loading software classes, such as Java™ classes, is class verification. During class verification, a virtual machine (VM), such as a Java™ virtual machine (JVM™), scans the class being loaded to ensure that bytecode and class constructs conform to the programming language standard of the VM. Class verification can improve security, because it can prevent a malicious class from accessing data that it should not have access to. Class verification also ensures that malformed classes do not compromise the operation and stability of the VM. Unfortunately, a major drawback to class verification is the associated processing overhead that can result in a system startup delay. For example, existing class verification techniques may account for upwards of 10% or more of system initialization time, thereby reducing system responsiveness and availability.
One technology that may decrease class verification time for Java™ applications is a J9 executable (JXE). Using a JXE, classes may be verified and loaded into a JVM™. The internal JVM™ representation can then be stored to a binary file, essentially creating an executable library from the Java™ program. One problem with JXEs is that Java™ classes must be preprocessed to generate and verify the JXE files. If a class is changed or the application is upgraded, then the JXEs also need to be regenerated. Since a single JXE usually contains numerous classes that must be loaded entirely into memory, JXEs may consume a larger amount of memory beyond the desired classes to load, decreasing resource utilization efficiency and increasing load time. In addition to these drawbacks, JXE technology is not supported on many Java™ developed kit platforms because of shared class constraints, resulting in compatibility issues.
Shared classes can give a VM the ability to keep a cache of loaded classes in shared volatile memory. After an application is started for the first time, it can load the classes from shared memory instead of a disk on which the classes are stored. This approach may result in a similar startup time improvement as JXEs, and is less disruptive to the Java™ programming model. However, because shared classes support seamlessly loading classes from the class cache and from the disk, most of the performance savings are related to reduced access delays, but full class verification is still required. Additionally, when a system using shared classes reboots, the class cache must be populated again from the disk, so applications do not get the performance benefit of shared classes after each reboot. Rapid startup after a system reboot is important to high availability systems, because faster application startup times result in less downtime, and thus a higher availability rating for the system. Thus, shared classes do not substantially reduce system initialization overhead time related to class verification.
Some componentization frameworks have component lifecycle features that may appear to improve verification time at startup. For example, frameworks such as the Open Services Gateway initiative (OSGi) framework may support binary verification of component bundles to ensure that a component being loaded by the framework is the same code shipped by the component provider. These features only provide limited security and cannot provide performance improvements in class loading for several reasons. First, OSGi framework implementations are made of Java™ classes that run on a Java™ platform. Therefore, they are subject to the same rules as any Java™ class. Only internal changes in the JVM™ can affect whether or not classes are verified and in what manner. Secondly, bundle verification only verifies the authenticity of the code. Java™ class verification is not performed to verify the authenticity of the binaries. It is performed to make sure that the binaries are not malformed or non-compliant to the Java™ programming language standard. However, OSGi framework implementations do not verify that the binaries will not de-stabilize the JVM™ or violate the JVM™ specification through authenticity checks. Some OSGi bundles can be very large (e.g., 50 megabytes), but most of the classes inside of them are not loaded initially. Performing binary verification on the entire bundle would likely slow down overall system performance, because only a small portion of the classes in the bundle may need to be loaded at startup. Additionally, an OSGi bundle may include files that are not subject to class verification, such as XML, properties, and configuration files, creating a verification gap for the entire OSGi bundle.
Therefore, existing techniques do not improve class-loading performance to reduce system initialization time while providing secure class verification. Accordingly, there is a need in the art for class verification with improved class-loading performance.